package com.ruoyi.tzai.config;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import com.ruoyi.tzai.domain.TaskQueue;
import com.ruoyi.tzai.service.ITaskQueueService;
import com.ruoyi.tzai.service.task.ITaskExecutorService;

/**
 * 任务恢复管理器
 * 在Spring容器启动完成后，自动扫描并恢复中断的任务
 * 
 * @author tzai
 * @date 2025-11-12
 */
@Component
public class TaskRecoveryManager implements ApplicationListener<ContextRefreshedEvent> 
{
    private static final Logger log = LoggerFactory.getLogger(TaskRecoveryManager.class);

    @Autowired
    private ITaskQueueService taskQueueService;

    @Autowired
    private ITaskExecutorService taskExecutorService;

    @Value("${tzai.task.recovery.auto-recovery:true}")
    private boolean autoRecovery;

    @Value("${tzai.task.recovery.max-recovery-tasks:10}")
    private int maxRecoveryTasks;

    private boolean hasRun = false;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) 
    {
        // 防止重复执行（Spring可能触发多次）
        if (hasRun) {
            return;
        }
        hasRun = true;

        if (!autoRecovery) {
            log.info("任务自动恢复已禁用");
            return;
        }

        log.info("========== 开始恢复中断的任务 ==========");

        try {
            // 1. 查找中断的任务（status='running'）
            List<TaskQueue> interruptedTasks = taskQueueService.selectInterruptedTasks();

            if (interruptedTasks.isEmpty()) {
                log.info("没有发现中断的任务");
                return;
            }

            log.info("发现 {} 个中断的任务", interruptedTasks.size());

            // 2. 限制恢复数量
            int recoverCount = Math.min(interruptedTasks.size(), maxRecoveryTasks);

            int successCount = 0;
            int failCount = 0;

            // 3. 逐个恢复
            for (int i = 0; i < recoverCount; i++) {
                TaskQueue task = interruptedTasks.get(i);
                try {
                    log.info("恢复任务: taskId={}, articleId={}, currentStep={}, progress={}%",
                             task.getTaskId(),
                             task.getArticleId(),
                             task.getCurrentStep(),
                             task.getTotalProgress());

                    // 重置状态为待恢复
                    task.setStatus("resuming");
                    task.setWorkerThread(null);
                    taskQueueService.updateTaskQueue(task);

                    // 从断点继续执行
                    taskExecutorService.resumeFromBreakpoint(task.getTaskId());

                    successCount++;

                    log.info("任务恢复成功: taskId={}", task.getTaskId());

                } catch (Exception e) {
                    failCount++;
                    log.error("任务恢复失败: taskId={}", task.getTaskId(), e);

                    // 标记为失败
                    task.setStatus("failed");
                    task.setErrorMessage("恢复失败: " + e.getMessage());
                    taskQueueService.updateTaskQueue(task);
                }
            }

            log.info("========== 任务恢复完成: 成功={}, 失败={}, 跳过={} ==========",
                     successCount, failCount, interruptedTasks.size() - recoverCount);

        } catch (Exception e) {
            log.error("任务恢复过程发生异常", e);
        }
    }
}

